from drf_yasg.inspectors import SwaggerAutoSchema
from drf_yasg.utils import get_serializer_ref_name
from rest_framework import serializers


class NotHandledSerializer(serializers.Serializer):
    class Meta:
        ref_name = '未定义'


class BasePageSerializer(serializers.Serializer):
    page = serializers.IntegerField(label='当前页码')
    count = serializers.IntegerField(label='数据总数')
    results = serializers.ListSerializer(label='结果数据集', child=NotHandledSerializer())

    class Meta:
        ref_name = ''


class BaseResponseSerializer(serializers.Serializer):
    msg = serializers.CharField(label='返回信息')
    code = serializers.IntegerField(label='返回码')
    data = NotHandledSerializer()

    class Meta:
        ref_name = ''


class BasePageResponseSerializer(serializers.Serializer):
    msg = serializers.CharField(label='返回信息')
    code = serializers.IntegerField(label='返回码')
    data = serializers.ListSerializer(child=NotHandledSerializer(), label='返回数据集')

    class Meta:
        ref_name = ''


class CustomActionAutoSchema(SwaggerAutoSchema):

    def custom_defined(self):
        return self.overrides.get('query_serializer', None)

    def should_filter(self):
        should_filter = super().should_filter()

        return should_filter and not self.custom_defined()

    def should_page(self):
        should_page = super().should_page()

        return should_page and self.overrides.get('should_page', True)

    def get_paginated_response(self, response_schema):
        """
        ModelViewSet Get 请求的默认返回值加上了【msg, data, code】，并且在data中加入了【results, page, count】
        """

        # 获取model_serializer以及ref_name
        _view_serializer = getattr(self.view, 'serializer_class')()
        ref_name = get_serializer_ref_name(_view_serializer)

        # 将model_serializer赋值给page_serializer的results字段，并修改其ref_name
        _base_page = BasePageSerializer()
        getattr(_base_page, '_declared_fields')['results'] = serializers.ListSerializer(
            child=_view_serializer, label='返回数据集')
        _base_page.Meta.ref_name = f'{ref_name}_data'

        # 将page_serializer赋值给response_serializer的data字段，并修改其ref_name
        _serializer = BasePageResponseSerializer()
        getattr(_serializer, '_declared_fields')['data'] = _base_page
        _serializer.Meta.ref_name = f'{ref_name}_response'

        return _serializer
